package web.directories.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import domain.entities.*;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.springframework.beans.factory.annotation.Autowired;
import services.AddressService;
import services.CriteriaEthicsCommittee;
import services.EthicsCommitteeCRUDService;
import services.MailService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Namespace("/Directories/EthicsCommittee")
public class EthicsCommitteeController extends ActionSupport implements ModelDriven, ServletResponseAware, ServletRequestAware {

    private EthicsCommitteeCRUDService service;
    private AddressService addressService;
    private MailService mailService;

    private List<ComiteEtica> list = new ArrayList<ComiteEtica>();
    private ComiteEtica comiteEtica = new ComiteEtica();
    private String editableCommitteeId;
    private String editContactPersonId;
    private List<Countries> countries = new ArrayList<Countries>();
    private List<Regions> regions = new ArrayList<Regions>();
    private List<Cities> cities = new ArrayList<Cities>();
    private Countries countrySelected;
    private Regions regionSelected;
    private Cities citySelected;
    private ContactPerson contactPerson = new ContactPerson();
    private String comiteEticaName;
    private String comiteCategoria;
    private ComiteEtica.YesNo iecFee;

    private File schedule;
    private String scheduleContentType;
    private String scheduleFileName;

    private File sop;
    private String sopContentType;
    private String sopFileName;

    private String isSop;

    private HttpServletRequest request;
    private HttpServletResponse response;

    private List<String> rolesInCommittee = new ArrayList<String>();

    @Autowired
    public EthicsCommitteeController(EthicsCommitteeCRUDService service,
                                     AddressService addressService, MailService mailService) {
        this.service = service;
        this.addressService = addressService;
        this.mailService = mailService;
        comiteEtica.setAddress(new Address());
        countries = this.addressService.getCountries();
    }

    @Action(value="main", results={
            @Result(name="success", location="/directories.ethicsCommittee.tiles", type="tiles")
    })
    public String execute() {
        list = new ArrayList<ComiteEtica>(0);
        return SUCCESS;
    }

    @Action(value="list", results={
            @Result(name="success", location="/directories.ethicsCommittee.tiles", type="tiles")
    })
    public String list() {

        CriteriaEthicsCommittee cr = new CriteriaEthicsCommittee(comiteEtica);
        list = service.list(cr);

        return SUCCESS;
    }

    @Action(value="create", results={
            @Result(name="success",location="/directories.ethicsCommittee.create.tiles", type="tiles")
    })
    public String create() {
        if(editableCommitteeId != null){
            int id = Integer.parseInt(editableCommitteeId);
            comiteEtica = service.findById(id);

            countrySelected = addressService.getCountryByName(comiteEtica.getAddress().getCountry());

            regions = addressService.getRegions(countrySelected.getCountryId());
            regionSelected = addressService.getRegionByName(comiteEtica.getAddress().getProvince(), countrySelected.getCountryId().toString());

            cities = addressService.getCities(regionSelected.getRegionId());

            citySelected = addressService.getCityByName(comiteEtica.getAddress().getCity(), regionSelected.getRegionId().toString(), countrySelected.getCountryId().toString());

            Iterator<ContactPerson> itContacts = comiteEtica.getContactPersons().iterator();
            int index = 0;
            rolesInCommittee.clear();
            while(itContacts.hasNext()){
                rolesInCommittee.add(itContacts.next().getRoleInCommittee().getId().toString());
            }

        }
        return SUCCESS;
    }

    @Action(value="save", results={
            @Result(name="success",location="main", type="redirectAction")
    })
    public String save() throws IOException {
        if(comiteEtica.getAddress().getCity() != null)
            addressService.checkCity(comiteEtica.getAddress().getCity(),
                    comiteEtica.getAddress().getProvince(),
                    comiteEtica.getAddress().getCountry()
            );

        Iterator<String> itRoles = rolesInCommittee.iterator();
        int index = 0;
        while(itRoles.hasNext()){
            String actual = itRoles.next();
            if(actual != null && !actual.equals("-1")){
                ContactPerson.RoleInCommittee role = ContactPerson.RoleInCommittee.values()[Integer.parseInt(actual)];
                comiteEtica.getContactPersons().get(index).setRoleInCommittee(role);
            }
            index++;
        }

        if(schedule != null){
            comiteEtica.setFileNameSchedule(scheduleFileName);
            FileInputStream fis;
            byte[] content = null;
            fis = new FileInputStream(schedule);
            content = new byte[fis.available()];
            fis.read(content);
            fis.close();
            comiteEtica.setFileSchedule(content);
        }
        if(sop != null){
            comiteEtica.setFileNameSop(sopFileName);
            FileInputStream fis;
            byte[] content = null;
            fis = new FileInputStream(sop);
            content = new byte[fis.available()];
            fis.read(content);
            fis.close();
            comiteEtica.setFileSop(content);
        }
        service.save(comiteEtica);

        rolesInCommittee.clear();

        return SUCCESS;
    }

    @Action(value="downloadFile", results={
            @Result(name="success",location="/directories.ethicsCommittee.create.tiles", type="tiles")
    })
    public String downloadFile() throws IOException {
        if( comiteEtica.getId() != null && comiteEtica.getId() != 0){
            ComiteEtica ce = service.findById(comiteEtica.getId());
            if(isSop.equals("1")){
                if( ce.getFileSop() != null){
                    String[] ext = ce.getFileNameSop().split("\\.");
                    // Initialize response.
                    response.reset();
                    if( ext[1].equals("pdf"))
                        response.setContentType("application/pdf");
                    else
                        response.setContentType("application/doc");
                    response.setHeader("Content-disposition", "attachment; filename=\""+ce.getFileNameSop()+"\"");
                    // Write file to response.
                    OutputStream output = response.getOutputStream();
                    output.write(ce.getFileSop());
                    output.close();
                }
            }
            else{
                if( ce.getFileSchedule() != null){
                    String[] ext = ce.getFileNameSchedule().split("\\.");
                    // Initialize response.
                    response.reset();
                    if( ext[1].equals("pdf"))
                        response.setContentType("application/pdf");
                    else
                        response.setContentType("application/doc");
                    response.setHeader("Content-disposition", "attachment; filename=\""+ce.getFileNameSchedule()+"\"");
                    // Write file to response.
                    OutputStream output = response.getOutputStream();
                    output.write(ce.getFileSchedule());
                    output.close();
                }
            }
        }
        return SUCCESS;
    }


    @Override
    public Object getModel() {
        return comiteEtica;
    }

    @Action(value="delete", results={
            @Result(name="success",location="main", type="redirectAction")
    })
    public String delete() {
        if(editableCommitteeId != null){
            int id = Integer.parseInt(editableCommitteeId);
            comiteEtica = service.findById(id);
            service.delete(comiteEtica);
        }
        return SUCCESS;
    }


    @Action(value="getComiteEticaByName", results={
            @Result(name="success",location="/WEB-INF/jsp/Protocols/investigator/comitesEticaWindow.jsp")
    })
    public String getComiteEticaByName() {
        list = service.findByName(comiteEticaName);
        Iterator<ComiteEtica> it = list.iterator();
        ComiteEtica.Category category = ComiteEtica.Category.values()[Integer.parseInt(comiteCategoria)];
        while(it.hasNext()){
            ComiteEtica ce =it.next();
            if(!ce.getCategory().equals(category)){
                it.remove();
            }
        }
        return SUCCESS;
    }

    public String getComiteEticaName() {
        return comiteEticaName;
    }

    public void setComiteEticaName(String comiteEticaName) {
        this.comiteEticaName = comiteEticaName;
    }

    public List<ComiteEtica> getList() {
        return list;
    }

    public void setList(List<ComiteEtica> list) {
        this.list = list;
    }

    public ComiteEtica getComiteEtica() {
        return comiteEtica;
    }

    public void setComiteEtica(ComiteEtica comiteEtica) {
        this.comiteEtica = comiteEtica;
    }

    public String getEditableCommitteeId() {
        return editableCommitteeId;
    }

    public void setEditableCommitteeId(String editableCommitteeId) {
        this.editableCommitteeId = editableCommitteeId;
    }

    public List<Countries> getCountries() {
        return countries;
    }

    public void setCountries(List<Countries> countries) {
        this.countries = countries;
    }

    public List<Regions> getRegions() {
        return regions;
    }

    public void setRegions(List<Regions> regions) {
        this.regions = regions;
    }

    public List<Cities> getCities() {
        return cities;
    }

    public void setCities(List<Cities> cities) {
        this.cities = cities;
    }

    public Countries getCountrySelected() {
        return countrySelected;
    }

    public void setCountrySelected(Countries countrySelected) {
        this.countrySelected = countrySelected;
    }

    public Regions getRegionSelected() {
        return regionSelected;
    }

    public void setRegionSelected(Regions regionSelected) {
        this.regionSelected = regionSelected;
    }

    public Cities getCitySelected() {
        return citySelected;
    }

    public void setCitySelected(Cities citySelected) {
        this.citySelected = citySelected;
    }

    public ContactPerson getContactPerson() {
        return contactPerson;
    }

    public void setContactPerson(ContactPerson contactPerson) {
        this.contactPerson = contactPerson;
    }

    public String getEditContactPersonId() {
        return editContactPersonId;
    }

    public void setEditContactPersonId(String editContactPersonId) {
        this.editContactPersonId = editContactPersonId;
    }

    public ComiteEtica.Category[] getCategories() {
        return ComiteEtica.Category.values();
    }

    public ComiteEtica.ECMeetingFrecuency[] getFrecuencies(){
        return ComiteEtica.ECMeetingFrecuency.values();
    }

    public ComiteEtica.TimeToProvideDocuments[] getTimeToProvide(){
        return ComiteEtica.TimeToProvideDocuments.values();
    }

    public ComiteEtica.YesNo[] getYesNo(){
        return ComiteEtica.YesNo.values();
    }

    public void setTimeToProvideDocumentApprovalsC(String id){
        ComiteEtica.TimeToProvideDocuments t = ComiteEtica.TimeToProvideDocuments.values()[Integer.parseInt(id)];
        comiteEtica.setTimeToProvideDocumentApprovals(t);
    }

    public ComiteEtica.YesNo getIecFee() {
        if (comiteEtica.getFee().getId() != null)
            iecFee = ComiteEtica.YesNo.values()[0];
        else
            iecFee = ComiteEtica.YesNo.values()[1];
        return iecFee;
    }

    public void setIecFee(String id) {
        if(id.equals("1"))
            comiteEtica.setFee(null);
    }

    public void setShouldBePaidBeforeDocumentSubmissionC(String id){
        ComiteEtica.YesNo t = ComiteEtica.YesNo.values()[Integer.parseInt(id)];
        comiteEtica.getFee().setShouldBePaidBeforeDocumentSubmission(t);
    }

    public void setGcpComplianceC(String id){
        ComiteEtica.YesNo t = ComiteEtica.YesNo.values()[Integer.parseInt(id)];
        comiteEtica.setGcpCompliance(t);
    }

    public void setCategoryC(String id){
        ComiteEtica.Category category = ComiteEtica.Category.values()[Integer.parseInt(id)];
        comiteEtica.setCategory(category);
    }

    public void setMeetingFrecuencyC(String id){
        ComiteEtica.ECMeetingFrecuency f = ComiteEtica.ECMeetingFrecuency.values()[Integer.parseInt(id)];
        comiteEtica.setEcMeetingFrecuency(f);
    }

    public void setEvaluateDocumentsInEnglishC(String id){
        ComiteEtica.YesNo t = ComiteEtica.YesNo.values()[Integer.parseInt(id)];
        comiteEtica.setEvaluateDocumentsInEnglish(t);
    }

    public void setAllSingedDatedStampedC(String id){
        ComiteEtica.YesNo t = ComiteEtica.YesNo.values()[Integer.parseInt(id)];
        comiteEtica.setAllSingedDatedStamped(t);
    }

    public void setRegisteredC(String id){
        ComiteEtica.YesNo t = ComiteEtica.YesNo.values()[Integer.parseInt(id)];
        comiteEtica.setRegistered(t);
    }

    public void setSopsWrittenC(String id){
        ComiteEtica.YesNo t = ComiteEtica.YesNo.values()[Integer.parseInt(id)];
        comiteEtica.setSopsWritten(t);
    }

    public ContactPerson.RoleInCommittee[] getRoleInCommitteeList(){
        return ContactPerson.RoleInCommittee.values();
    }

    public ContactPerson.Degree[] getDegreeList(){
        return ContactPerson.Degree.values();
    }


    public String getComiteCategoria() {
        return comiteCategoria;
    }

    public void setComiteCategoria(String comiteCategoria) {
        this.comiteCategoria = comiteCategoria;
    }

    public void setSopFileName(String sopFileName) {
        this.sopFileName = sopFileName;
    }

    public void setSchedule(File schedule) {
        this.schedule = schedule;
    }

    public void setScheduleContentType(String scheduleContentType) {
        this.scheduleContentType = scheduleContentType;
    }

    public void setScheduleFileName(String scheduleFileName) {
        this.scheduleFileName = scheduleFileName;
    }

    public void setSop(File sop) {
        this.sop = sop;
    }

    public void setSopContentType(String sopContentType) {
        this.sopContentType = sopContentType;
    }

    public String getSopFileName() {
        return sopFileName;
    }

    public File getSchedule() {
        return schedule;
    }

    public String getScheduleContentType() {
        return scheduleContentType;
    }

    public String getScheduleFileName() {
        return scheduleFileName;
    }

    public File getSop() {
        return sop;
    }

    public String getSopContentType() {
        return sopContentType;
    }

    public List<String> getRolesInCommittee() {
        return rolesInCommittee;
    }

    public void setRolesInCommittee(List<String> rolesInCommittee) {
        this.rolesInCommittee = rolesInCommittee;
    }

    public String getIsSop() {
        return isSop;
    }

    public void setIsSop(String sop) {
        this.isSop = sop;
    }

    @Override
    public void setServletRequest(javax.servlet.http.HttpServletRequest request) {
        this.request   = request;
    }

    @Override
    public void setServletResponse(javax.servlet.http.HttpServletResponse response) {
        this.response = response;
    }
}
